package com.wyh.yuhcloud.controller;


import com.wyh.yuhcloud.core.Result;
import com.wyh.yuhcloud.dto.AddUserDto;
import com.wyh.yuhcloud.dto.LoginUserDto;
import com.wyh.yuhcloud.dto.ResultDto;
import com.wyh.yuhcloud.service.SysLoginService;
import com.wyh.yuhcloud.service.UserService;
import com.wyh.yuhcloud.util.R;
import com.wyh.yuhcloud.util.RedisUtils;

import com.wyh.yuhcloud.util.TokenManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.NestedServletException;



import javax.servlet.http.HttpServletRequest;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * @author wyh
 * @version 1.0
 * @date 2022/2/24 16:53
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private SysLoginService sysLoginService;

    @Autowired
    private RedisUtils redisUtils;
    /**
     * 用户登录
     * @param loginUserDto 登录信息
     * @return token
     */
    @PostMapping("/login")
    public Result LoginUser(@RequestBody LoginUserDto loginUserDto){
        log.warn("登录用户为："+loginUserDto);
        ResultDto login = sysLoginService.login(loginUserDto.getUserName(), loginUserDto.getUserPassword(), loginUserDto.getRememberMe());
        if (login!=null){
            log.info("用户登录{}--{}",login.getUserId(),login.getToken());
        }else {
            log.info("用户登录--错误的验证");
        }
        assert login != null;
        login.setUserName(loginUserDto.getUserName());

        return new Result(login);
    }

    private String hashMd5(String pwd) {
        try {
            //生成加密计算器
            MessageDigest md = MessageDigest.getInstance("MD5");
            //计算md5函数
            md.update(pwd.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8位字符串。因为md5 hash值是16位的hex值，实际上就是8位
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示﹔得到字符串形式的hash值
            //一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方)
            return new BigInteger(1,md.digest()).toString();
        } catch (Exception e) {
            throw new RuntimeException("加密失败");
        }
    }

    /**
     * 注册用户
     * @param addUserDto 添加数据流
     * @return 成功
     */
    @PostMapping("/signUp")
    public Result signUpUser(@RequestBody AddUserDto addUserDto){
        if (redisUtils.hasKey(addUserDto.getUserEmail())){
            String sign = userService.signUp(addUserDto);
            log.warn("注册结果--"+sign);
            return new Result(sign);
        }
        else {
            return new Result("验证码错误或失效");
        }
    }

    /**
     * 发送验证码
     * @param mail 目标邮箱
     * @return 验证码和对应时间
     */
    @GetMapping("/mailCheck/{mail}")
    public Result mailCheck(@PathVariable("mail") String mail){
        try {
            log.info("申请注册邮箱为--"+mail);
            userService.mailCheck(mail);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(10000,"系统繁忙，请稍后再试！");
        }
        return new Result();
    }

    /**
     * 获取等级
     * @param userId
     * @return
     */
    @GetMapping("/queryVersion/{userId}")
    public Result queryVersionUser(@PathVariable("userId") String userId){
        Integer version  = userService.selectPermissionValueByUserId(userId);
        log.info("访问用户名为--"+userId+"访问权限等级为--"+version);
        return new Result(version);
    }

    /**
     * 注销
     * @param request
     * @return
     */
    @PostMapping("logout")
    public R UserLogout(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        //判断token是否为空,移除token,从redis中删除token
        if (token!=null) {
            String username = tokenManager.getUserInfoFromToken(token);
            redisUtils.del(username);
            redisUtils.del(token);
            log.info("用户注销："+token) ;
        }
        return R.ok();
    }
}
